package org.c41.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import org.c41.system.ICloseable;

public class TCPSocket implements ICloseable{

	private Socket socket;
	private ObjectOutputStream out;
	private ObjectInputStream in;
	
	private boolean autoFlush = true;
	
	public TCPSocket(String host, int port) throws UnknownHostException, IOException{
		this(new Socket(host,port));
	}
	
	TCPSocket(Socket socket) throws IOException{
		this.socket=socket;
		this.out=new ObjectOutputStream(socket.getOutputStream());
		this.in=new ObjectInputStream(socket.getInputStream());
	}

	public void send(int bb) throws IOException{
		out.write(bb);
		m_check_flush();
	}
	
	public void send(byte[] bb) throws IOException{
		out.write(bb);
		m_check_flush();
	}
	
	public void send(byte[] bb, int off, int length) throws IOException{
		out.write(bb,off,length);
		m_check_flush();
	}
	
	public void sendString(String str) throws IOException{
		out.writeUTF(str);
		m_check_flush();
	}
	
	public void sendInt(int i) throws IOException{
		out.writeInt(i);
		m_check_flush();
	}
	
	public void sendShort(short s) throws IOException{
		out.writeShort(s);
		m_check_flush();
	}
	
	public void sendDouble(double d) throws IOException{
		out.writeDouble(d);
		m_check_flush();
	}
	
	public void sendLong(long l) throws IOException{
		out.writeLong(l);
		m_check_flush();
	}
	
	public void sendByte(byte b) throws IOException{
		out.writeByte(b);
		m_check_flush();
	}
	
	public void sendChar(char c) throws IOException{
		out.writeChar(c);
		m_check_flush();
	}
	
	public void sendBoolean(boolean b) throws IOException{
		out.writeBoolean(b);
		m_check_flush();
	}
	
	public void sendObject(Object obj) throws IOException{
		out.writeObject(obj);
		m_check_flush();
	}
	
	public int receive() throws IOException{
		return in.read();
	}
	
	public int receive(byte[] bb) throws IOException{
		return in.read(bb);
	}
	
	public int receive(byte[] bb, int off, int length) throws IOException{
		return in.read(bb,off,length);
	}
	
	public int receiveInt() throws IOException{
		return in.readInt();
	}
	
	public double receiveDouble() throws IOException{
		return in.readDouble();
	}
	
	public short receiveShort() throws IOException{
		return in.readShort();
	}
	
	public boolean receiveBoolean() throws IOException{
		return in.readBoolean();
	}
	
	public long receiveLong() throws IOException{
		return in.readLong();
	}
	
	public String receiveString() throws IOException{
		return in.readUTF();
	}
	
	public byte receiveByte() throws IOException{
		return in.readByte();
	}
	
	public char receiveChar() throws IOException{
		return in.readChar();
	}
	
	public Object receiveObject() throws ClassNotFoundException, IOException{
		return in.readObject();
	}
	
	public void setAutoFlush(boolean b){
		this.autoFlush=b;
	}
	
	public boolean isAutoFlush(){
		return this.autoFlush;
	}
	
	@Override
	public void close() throws IOException {
		socket.close();
	}

	@Override
	public boolean isClosed() {
		return socket.isClosed();
	}
	
	private void m_check_flush() throws IOException{
		if(autoFlush){
			flush();
		}
	}

	public void flush() throws IOException {
		out.flush();
	}
	
}
